package com.shotinthedark
{
	import com.common.dataStructures2.Array2;
	import com.common.physics.CollisionDetection;
	import com.common.screens.PlayScreen;
	import com.common.utils.Math2;
	import com.common.utils.TransformEZ;
	import com.shootingGame.GamePlayManager;
	import com.shootingGame.Player;
	import com.shootingGame.mapClasses.Map;
	import com.shootingGame.mapClasses.TileSet;
	import com.shootingGame.physics.ShooterPhysics;
	import com.shootingGame.renderableClasses.GameObject;
	import com.shootingGame.renderableClasses.PickupObject;
	import com.shootingGame.weaponsClasses.Weapon;
	import com.shootingGame.weaponsClasses.ordinance.Ordinance;
	import com.shotinthedark.tileSets.SampleTileSet;
	import com.shotinthedark.weapons.BasicGunWeapon;
	import com.shotinthedark.weapons.GuidedRocketWeapon;
	import com.shotinthedark.weapons.MachineGunWeapon;
	
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;
//	import flash.utils.getTimer;

	public class GamePlay extends GamePlayManager
	{
		
		public var primaryUserName : String;
		public var maskHolder : MovieClip;
		private var player2 : Player;
		private var viewCone : MovieClip;
		private var tileData : Array2;
		//private var PLAYER_DISTANCE_FROM_CENTER_TOLERANCE : Number = 5;
		
		public function GamePlay(playScreen:PlayScreen):void
		{
			super(playScreen);
			viewRect = new Rectangle(0, 0, stageWidth, stageHeight);
			updateTimer.start();
		}
		
		override protected function loadMap():void{
//			var obj:Object = {
//				0, 0, 0, 0, 0,
//				1, 1, 1, 1, 1
//			};
//			var arr1:Array = new Array();
//			arr1.push(0, 1, 0, 1, 0);
//			var arr2:Array = new Array();
//			arr2.push(1, 0, 1, 0, 1);
//			tileData = new Array2(5, 2);
//			tileData.appendRow(arr1);			
//			tileData.appendRow(arr2);
			var sampleTileSet : TileSet = new SampleTileSet();
			GamePlayManager.TILE_WIDTH = 50;//sampleTileSet.getChildAt(0).width;
			GamePlayManager.TILE_HEIGHT = 50;//sampleTileSet.getChildAt(0).height;
			GamePlayManager.MAP_NUMTILES_HORIZONTAL = 31;
			GamePlayManager.MAP_NUMTILES_VERTICAL = 14;
			tileData = new Array2(GamePlayManager.MAP_NUMTILES_HORIZONTAL, GamePlayManager.MAP_NUMTILES_VERTICAL);
			tileData.push(
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
			);
//			tileData.push(
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1,
//			1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
//			1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1
//			);
			map = new Map("Sample Map",  GamePlayManager.MAP_NUMTILES_HORIZONTAL, GamePlayManager.MAP_NUMTILES_VERTICAL, GamePlayManager.TILE_WIDTH, GamePlayManager.TILE_HEIGHT, tileData, sampleTileSet);
			mapHolder.addChild(map.displayMap);
		}
		
		override protected function initializeGame():void{
			maskHolder = playScreen.arena.maskHolder;
			player1 = new Player(true, new DummyPlayer(), null, 0, 0);
			
			viewCone = new ViewConeMask();
//			maskHolder.addChild(viewCone);
			desiredViewPosition = new Point(stageWidth/2.0, stageHeight/2.0);
			viewCone.x = player1.memoryX;
			viewCone.y = player1.memoryY;
			//player1.darkRegion = playScreen.arena.darknessHolder;
			//player1.weapon = new BasicGunWeapon(4,20);
			playerHolder.addChild(player1);
			//ordinanceCollisionList = new CollisionList(player1);
			initDemo()
		}
		
		private function initDemo() : void {
			 var enemy:Player = spawnEnemy(); 
			 enemy.keyStates.MOUSE_X = 800;
			 enemy.keyStates.MOUSE_Y = 500;
			 enemy.weapon = new MachineGunWeapon();
			 enemy.keyStates.MOUSELEFT_DOWN = true;
			 
		}
		
		private function spawnEnemy() : Player {
			player2 = new Player(false, new DummyPlayer(), null, Math2.rand(50,750), Math2.rand(50,550));
			TransformEZ.setColor(player2.model.body, 0x663300);
			TransformEZ.setColor(player2.model.face, 0x999900);
			playerHolder.addChild(player2);
		}
		
		private function spawnWeaponPickup(weaponType:int, xPos:int, yPos:int) : void {
			var spawnPoint : Point;
			var weaponPickup : PickupObject;
			spawnPoint = new Point(xPos, yPos);
			
			switch(weaponType){
				case 0:{
					weaponPickup = BasicGunWeapon.getPickupObject();
					break;
				}
				case 1:{
					weaponPickup = MachineGunWeapon.getPickupObject();
					break;
				}
				case 2:{
					weaponPickup = GuidedRocketWeapon.getPickupObject();
					break;
				}
				default:{
					break;
				}
			}
			weaponPickup.truePosition = spawnPoint;
			pickupHolder.addChild(weaponPickup);
			
//			spawnPoint = new Point (Math2.rand(0, playScreen.stage.stageWidth), Math2.rand(0, playScreen.stage.stageHeight));
//			weaponPickup = BasicGunWeapon.getPickupObject();
//			weaponPickup.truePosition = spawnPoint;
//			pickupHolder.addChild(weaponPickup);
//			
//			spawnPoint = new Point (Math2.rand(0, playScreen.stage.stageWidth), Math2.rand(0, playScreen.stage.stageHeight));
//			weaponPickup = MachineGunWeapon.getPickupObject();
//			weaponPickup.truePosition = spawnPoint;
//			pickupHolder.addChild(weaponPickup);			
//			
//			spawnPoint = new Point (Math2.rand(0, playScreen.stage.stageWidth), Math2.rand(0, playScreen.stage.stageHeight));
//			weaponPickup = GuidedRocketWeapon.getPickupObject();
//			weaponPickup.truePosition = spawnPoint;
//			pickupHolder.addChild(weaponPickup);
		}
		
		override public function onRender(evt : Event) : void {
			scrollView();
			if(viewCone){
					viewCone.rotation = player1.facing;
//					viewCone.x = x;
//					viewCone.y = y;
			}
			super.onRender(evt);
		}
		
				
		public function scrollView() : void {
			var globalPlayerPosition : Point = playerHolder.localToGlobal(new Point(player1.x, player1.y));			
			viewCone.x = globalPlayerPosition.x;
			viewCone.y = globalPlayerPosition.y;
//			var tweenSpeed:Number = 0.5;
//			if(Math2.getDistance(globalPlayerPosition.x, globalPlayerPosition.y, desiredViewPosition.x, desiredViewPosition.y) > PLAYER_DISTANCE_FROM_CENTER_TOLERANCE){
//				//GTween.defaultEase = fl.motion.easing.Sine.easeOut;			
//				var g:GTween = new GTween(mapHolder, tweenSpeed, {x:desiredViewPosition.x - player1.x, y:desiredViewPosition.y - player1.y});
//				g.play();
//				g = new GTween(playerHolder, tweenSpeed, {x:desiredViewPosition.x - player1.x, y:desiredViewPosition.y - player1.y});
//				g.play();
//				g = new GTween(pickupHolder, tweenSpeed, {x:desiredViewPosition.x - player1.x, y:desiredViewPosition.y - player1.y});
//				g.play();
//				g = new GTween(bulletHolder, tweenSpeed, {x:desiredViewPosition.x - player1.x, y:desiredViewPosition.y - player1.y});
//				g.play();
//				g = new GTween(effectsHolder, tweenSpeed, {x:desiredViewPosition.x - player1.x, y:desiredViewPosition.y - player1.y});
//				g.play();
//			}
			var newX:Number = desiredViewPosition.x - player1.x;
			var newY:Number = desiredViewPosition.y - player1.y;
			mapHolder.x = newX;
			mapHolder.y = newY;
			playerHolder.x = newX;
			playerHolder.y = newY;
			pickupHolder.x = newX;
			pickupHolder.y = newY;
			ordinanceHolder.x = newX;
			ordinanceHolder.y = newY;
			effectsHolder.x = newX;
			effectsHolder.y = newY;
			viewRect.x = player1.x - stageWidth/2.0;
			viewRect.y = player1.y - stageHeight/2.0;
		}
		
		override protected function ordinanceCollisions() : void {
			
			var globalPoint : Point;
			var ord:Ordinance;
			var positives : Array;
			var excluded : Array = new Array();
			var toDelete : Array;
			var target:GameObject;
			var targetCircleRadius:Number;
			var targetCircleCentre:Point;
			var targetCollidablePart:MovieClip;
			var i : int;
			var j : int;
			var n : int;
			var m : int;
//CDK collision detection of bullets and players... working, but all causes flickering??
//			for(i = 0; i < playerHolder.numChildren; i++) {
//				target = playerHolder.getChildAt(i) as GameObject;
//				ordinanceCollisionList.swapTarget(target.getCollidablePart());
//				
//				toDelete = new Array();
//				j = 0;
//				while(j < excluded.length) {
//					if(target != Ordinance(excluded[j]).owner){
//						ordinanceCollisionList.addItem(Ordinance(excluded[j]));
//						excluded.splice(j,1);
//					}
//					else
//						j++;
//				}
//				
//				toDelete = null;
//				
//				for(j = 0; j < bulletHolder.numChildren; j++) {
//					ord = bulletHolder.getChildAt(j) as Ordinance;
//					if(target == ord.owner){
//						excluded.push(ord);
//						ordinanceCollisionList.removeItem(ord);
//					}
//				}
//				
//				
//				positives = ordinanceCollisionList.checkCollisions();
//				for(j = 0; j < positives.length; j++) {
//					
////					if(flash.utils.getQualifiedSuperclassName(positives[j].object1).search("Ordinance") != -1){
//						ord = positives[j].object1;
////					}
////					else{
////						ord = positives[j].object2;
////					}
//					ord.isExpired = true;
//				}
//			}
			n = playerHolder.numChildren;
			for(i = 0; i < n; i++) {
				target = (playerHolder.getChildAt(i) as GameObject);
				m = ordinanceHolder.numChildren;
				try{
					for(j = 0; j < m; j++) {
						ord = (ordinanceHolder.getChildAt(j) as Ordinance);
					 	
					 	if(target != ord.owner){
					 		if(ShooterPhysics.detectObjectToOrdinanceCollision(target, ord)){
//					 			target.hitPoints -= ord.weaponInfo.damage;
//					 			ord.isExpired = true;
								target.collisionEffects.resolveCollisions();
								ord.collisionEffects.resolveCollisions();
					 			if(player2.isExpired)
					 				spawnEnemy();
					 		}
					 	}
					}
				}
				catch(Error){	
				}
			 }
//			 n = ordinanceHolder.numChildren;
//			 for(i = 0; i < n; i++) {
//			 	trace("start");
//			 	if(ShooterPhysics.detectAndResolveOrdinanceToTileCollision(ordinanceHolder.getChildAt(i) as GameObject)){
////			 		trace("true");				
//			 	}
//			 	trace("end");
//			 }
			 
			 i = 0;
			 while(i < ordinanceHolder.numChildren){
			 	if(ShooterPhysics.detectAndResolve_OrdinanceToTileCollision(ordinanceHolder.getChildAt(i) as GameObject))
			 		;
			 	i++;
			 }
		}
		
		override protected function playerCollisions() : void {
			var player:Player;
			var i : int;
			var n : int = playerList.length;
			for(i = 0; i < n; i++) {
				player = playerList[i] as Player;
				pickupCollisions(player);
				ShooterPhysics.detectAndResolve_PlayerToTileCollision(player);
			}
		}
		
		private function pickupCollisions(player:Player) : void {
			var playerCollidable:MovieClip = player.getCollidablePart();
			var collidable_Radius:Number = playerCollidable.width/2.0;
			var collidable_CentreX:Number = player.memoryX + playerCollidable.x;
			var collidable_CentreY:Number = player.memoryY + playerCollidable.y;
			var pickupPositionX:Number;
			var pickupPositionY:Number;
			var spawnPoint : Point;
			var pickup:PickupObject;
			var itemPickedUp:GameObject;
			var i : int;
			var n : int = pickupHolder.numChildren;
			for(i = 0; i < n; i++) {
				pickup = PickupObject(pickupHolder.getChildAt(i));
				if(CollisionDetection.pointCircleIntersection(collidable_Radius, collidable_CentreX, collidable_CentreY, pickup.memoryX, pickup.memoryY)){
					//pickupHolder.removeChild(pickup);
					itemPickedUp = pickup.pickedUp();
					pickup.removeObject_FromStage();
					pickup.removeObject_FromUpdateList();
					if(itemPickedUp is Weapon){
						(itemPickedUp as Weapon).attachedTo = player;
					}
					break;
//					spawnPoint = new Point (Math2.rand(0, playScreen.stage.stageWidth), Math2.rand(0, playScreen.stage.stageHeight));
//					pickup.truePosition = spawnPoint;
				}
			}
		}
	}
}
